/**
 * 命令执行系统使用示例
 * 
 * 演示如何在游戏逻辑中使用命令系统
 * 
 * @author AI Assistant
 * @date 2025-12-02
 */

import { ecs } from "../../../core/ecs/ECS";
import { LogicCmd } from "../command";
import { Vec3, Color } from "cc";

/**
 * 示例1：基本使用 - 角色移动系统
 * 
 * 在逻辑系统（20 FPS）中计算位置，通过命令更新渲染（60 FPS）
 */
export class CharacterMovementSystem extends ecs.System {
    private entity: ecs.Entity;
    private velocity: Vec3 = new Vec3(100, 0, 0);
    
    constructor(entity: ecs.Entity) {
        super();
        this.entity = entity;
    }
    
    update(dt: number): void {
        // 1. 计算逻辑（在 20 FPS 下执行）
        const currentPos = this.entity.node?.position || Vec3.ZERO;
        const newPos = currentPos.add(this.velocity.multiplyScalar(dt));
        
        // 2. 生成渲染命令（会在 60 FPS 下执行）
        LogicCmd.setPosition(this.entity, newPos);
        
        // 3. 根据方向旋转角色
        if (this.velocity.x > 0) {
            LogicCmd.setRotation(this.entity, 0);
        } else if (this.velocity.x < 0) {
            LogicCmd.setRotation(this.entity, 180);
        }
    }
}

/**
 * 示例2：动画控制 - 角色状态机
 */
export class CharacterAnimationSystem extends ecs.System {
    private entity: ecs.Entity;
    private state: 'idle' | 'walk' | 'run' | 'jump' = 'idle';
    
    constructor(entity: ecs.Entity) {
        super();
        this.entity = entity;
    }
    
    /**
     * 切换到行走状态
     */
    setState(newState: 'idle' | 'walk' | 'run' | 'jump'): void {
        if (this.state === newState) return;
        
        this.state = newState;
        
        // 使用命令播放动画
        switch (newState) {
            case 'idle':
                LogicCmd.playAnimation(this.entity, 'idle', true);
                break;
            case 'walk':
                LogicCmd.playAnimation(this.entity, 'walk', true);
                break;
            case 'run':
                LogicCmd.playAnimation(this.entity, 'run', true);
                break;
            case 'jump':
                LogicCmd.playAnimation(this.entity, 'jump', false);
                break;
        }
    }
    
    update(dt: number): void {
        // 根据速度自动切换动画
        // （实际游戏中会更复杂）
    }
}

/**
 * 示例3：UI 更新 - 血条系统
 */
export class HealthBarSystem extends ecs.System {
    private entity: ecs.Entity;
    private maxHealth: number = 100;
    private currentHealth: number = 100;
    
    constructor(entity: ecs.Entity) {
        super();
        this.entity = entity;
    }
    
    /**
     * 受到伤害
     */
    takeDamage(damage: number): void {
        this.currentHealth = Math.max(0, this.currentHealth - damage);
        this.updateHealthBar();
    }
    
    /**
     * 更新血条显示
     */
    private updateHealthBar(): void {
        const percentage = this.currentHealth / this.maxHealth;
        
        // 使用命令更新血条
        LogicCmd.setScale(this.entity, new Vec3(percentage, 1, 1));
        
        // 根据血量改变颜色
        if (percentage > 0.5) {
            LogicCmd.setSpriteColor(this.entity, new Color(0, 255, 0)); // 绿色
        } else if (percentage > 0.2) {
            LogicCmd.setSpriteColor(this.entity, new Color(255, 255, 0)); // 黄色
        } else {
            LogicCmd.setSpriteColor(this.entity, new Color(255, 0, 0)); // 红色
        }
        
        // 更新文本
        LogicCmd.setLabelText(this.entity, `${this.currentHealth}/${this.maxHealth}`);
    }
}

/**
 * 示例4：粒子效果 - 拾取物品反馈
 */
export class PickupEffectSystem extends ecs.System {
    /**
     * 播放拾取特效
     */
    playPickupEffect(entity: ecs.Entity): void {
        // 1. 放大动画
        const originalScale = entity.node?.scale || Vec3.ONE;
        LogicCmd.setScale(entity, originalScale.multiplyScalar(1.5));
        
        // 2. 闪烁效果
        LogicCmd.setSpriteColor(entity, new Color(255, 255, 0));
        
        // 3. 0.5秒后恢复
        setTimeout(() => {
            LogicCmd.setScale(entity, originalScale);
            LogicCmd.setSpriteColor(entity, Color.WHITE);
        }, 500);
    }
}

/**
 * 示例5：对象池 - 子弹系统
 */
export class BulletPoolSystem extends ecs.System {
    private pooledBullets: ecs.Entity[] = [];
    
    /**
     * 发射子弹
     */
    fireBullet(position: Vec3, direction: Vec3): void {
        // 从对象池获取或创建子弹
        const bullet = this.getPooledBullet();
        
        if (bullet) {
            // 使用命令激活和定位子弹
            LogicCmd.setPosition(bullet, position);
            LogicCmd.setActive(bullet, true);
            LogicCmd.setVisible(bullet, true);
            
            // 播放发射动画
            LogicCmd.playAnimation(bullet, 'fire', false);
        }
    }
    
    /**
     * 回收子弹
     */
    recycleBullet(bullet: ecs.Entity): void {
        // 使用命令隐藏子弹
        LogicCmd.setActive(bullet, false);
        LogicCmd.setVisible(bullet, false);
        
        this.pooledBullets.push(bullet);
    }
    
    private getPooledBullet(): ecs.Entity | null {
        return this.pooledBullets.pop() || null;
    }
}

/**
 * 示例6：批量操作 - 敌人波次管理
 */
export class EnemyWaveSystem extends ecs.System {
    /**
     * 生成一波敌人
     */
    spawnWave(enemies: ecs.Entity[]): void {
        enemies.forEach((enemy, index) => {
            // 错开出现时间
            setTimeout(() => {
                // 设置初始位置（屏幕外）
                const startPos = new Vec3(1000, index * 100, 0);
                LogicCmd.setPosition(enemy, startPos);
                
                // 激活敌人
                LogicCmd.setActive(enemy, true);
                LogicCmd.setVisible(enemy, true);
                
                // 播放出场动画
                LogicCmd.playAnimation(enemy, 'spawn', false);
                
                // 淡入效果
                LogicCmd.setSpriteOpacity(enemy, 0);
                setTimeout(() => {
                    LogicCmd.setSpriteOpacity(enemy, 255);
                }, 100);
            }, index * 200);
        });
    }
    
    /**
     * 清除所有敌人
     */
    clearWave(enemies: ecs.Entity[]): void {
        enemies.forEach(enemy => {
            // 播放死亡动画
            LogicCmd.playAnimation(enemy, 'death', false);
            
            // 1秒后销毁
            setTimeout(() => {
                LogicCmd.destroyNode(enemy);
            }, 1000);
        });
    }
}

/**
 * 示例7：视觉反馈 - 伤害数字飘字
 */
export class DamageTextSystem extends ecs.System {
    /**
     * 显示伤害数字
     */
    showDamage(damage: number, position: Vec3): void {
        // 假设有一个文本实体
        const textEntity = this.createTextEntity();
        
        if (textEntity) {
            // 设置位置和文本
            LogicCmd.setPosition(textEntity, position);
            LogicCmd.setLabelText(textEntity, `-${damage}`);
            LogicCmd.setLabelColor(textEntity, new Color(255, 0, 0));
            
            // 向上飘动
            const endPos = position.add(new Vec3(0, 100, 0));
            
            // 模拟飘动效果（实际应该用缓动系统）
            let progress = 0;
            const interval = setInterval(() => {
                progress += 0.1;
                if (progress >= 1) {
                    clearInterval(interval);
                    LogicCmd.destroyNode(textEntity);
                    return;
                }
                
                const currentPos = position.lerp(endPos, progress);
                LogicCmd.setPosition(textEntity, currentPos);
                LogicCmd.setSpriteOpacity(textEntity, Math.floor(255 * (1 - progress)));
            }, 50);
        }
    }
    
    private createTextEntity(): ecs.Entity | null {
        // 实际实现中应该从对象池获取
        return null;
    }
}

/**
 * 使用提示：
 * 
 * 1. 将这些系统注册到逻辑系统（20 FPS）：
 *    fixedUpdateManager.addSystem(new CharacterMovementSystem(entity));
 * 
 * 2. 命令会自动在渲染系统（60 FPS）中执行
 * 
 * 3. 好处：
 *    - 逻辑和渲染解耦
 *    - 自动帧率插值
 *    - 性能优化（批量处理）
 *    - 线程安全
 */

